from docx import Document
from docx.shared import Inches, Pt, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
from docx.oxml.ns import qn
import re
import logging

# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')


def set_font(style, font_name, font_size, bold=False, color=None):
    """设置样式的字体属性"""
    style.font.name = font_name
    style._element.rPr.rFonts.set(qn('w:eastAsia'), font_name)  # 支持中文字体
    style.font.size = Pt(font_size)
    style.font.bold = bold
    if color:
        style.font.color.rgb = color


def init_styles(doc):
    """初始化文档样式"""
    # 标题样式
    title_style = doc.styles.add_style('TitleStyle', 1)
    set_font(title_style, '微软雅黑', 16, bold=True)
    title_style.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
    title_style.paragraph_format.space_after = Pt(12)

    #  section标题样式
    section_style = doc.styles.add_style('SectionStyle', 1)
    set_font(section_style, '微软雅黑', 12, bold=True)
    section_style.paragraph_format.space_before = Pt(10)
    section_style.paragraph_format.space_after = Pt(6)
    section_style.paragraph_format.left_indent = Inches(0)

    # 正文样式
    normal_style = doc.styles['Normal']
    set_font(normal_style, '宋体', 10.5)
    normal_style.paragraph_format.space_after = Pt(0)
    normal_style.paragraph_format.line_spacing = 1.5

    # 项目符号样式
    list_style = doc.styles.add_style('ListStyle', 1)
    set_font(list_style, '宋体', 10.5)
    list_style.paragraph_format.space_after = Pt(0)
    list_style.paragraph_format.line_spacing = 1.5


def parse_content(content):
    """解析输入内容，提取各部分信息"""
    sections = {}
    current_section = None
    # 去除空行和可能的特殊符号（如#），并处理前后空格
    lines = [re.sub(r'^#+\s*', '', line).strip() for line in content.split('\n') if line.strip()]

    valid_sections = {'基本信息', '教育背景', '求职意向', '个人技能', '工作经历', '项目经验', '自我评价'}

    for line in lines:
        if line in valid_sections:
            current_section = line
            sections[current_section] = []
        elif current_section:
            sections[current_section].append(line)
        else:
            logging.warning(f"未识别的内容行（未归属任何 section）：{line}")

    return sections


def add_basic_info(doc, basic_info):
    """添加基本信息部分"""
    doc.add_paragraph('基本信息', style='SectionStyle')
    para = doc.add_paragraph()
    info_text = ' '.join(basic_info)
    parts = info_text.split(' ')
    for part in parts:
        if part:
            run = para.add_run(part + '  ')
            set_font(run, '宋体', 10.5)  # 复用字体设置逻辑


def add_education(doc, education_list):
    """添加教育背景部分"""
    doc.add_paragraph('教育背景', style='SectionStyle')
    for item in education_list:
        p = doc.add_paragraph(item, style='Normal')


def add_job_intention(doc, intention_list):
    """添加求职意向部分"""
    doc.add_paragraph('求职意向', style='SectionStyle')
    para = doc.add_paragraph()
    info_text = ' '.join(intention_list)
    parts = info_text.split(' ')
    for part in parts:
        if part:
            run = para.add_run(part + '  ')
            set_font(run, '宋体', 10.5)


def add_skills(doc, skills_list):
    """添加个人技能部分"""
    doc.add_paragraph('个人技能', style='SectionStyle')
    for skill in skills_list:
        # 替换特殊符号为标准项目符号
        skill_text = re.sub(r'^[Ø●○]', '•', skill)  # 支持更多符号替换
        p = doc.add_paragraph(skill_text, style='ListStyle')
        p.paragraph_format.left_indent = Inches(0.2)


def add_work_experience(doc, exp_list):
    """添加工作经历部分（用正则匹配日期）"""
    doc.add_paragraph('工作经历', style='SectionStyle')
    date_pattern = re.compile(r'^\d{4}\.\d{1,2}-\d{4}\.\d{1,2}|\d{4}\.\d{1,2}-至今')  # 匹配日期格式

    for exp in exp_list:
        p = doc.add_paragraph(style='Normal')
        # 提取日期部分并加粗
        date_match = date_pattern.match(exp)
        if date_match:
            date_text = date_match.group()
            rest_text = exp[len(date_text):].strip()
            date_run = p.add_run(date_text + '  ')
            date_run.bold = True
            p.add_run(rest_text)
        else:
            p.add_run(exp)  # 不匹配日期格式则直接添加


def add_project_experience(doc, project_list):
    """添加项目经验部分"""
    doc.add_paragraph('项目经验', style='SectionStyle')
    current_project = None
    project_title_pattern = re.compile(r'^项目[一二三四五六七八九十]：')  # 更通用的项目标题匹配

    for item in project_list:
        if project_title_pattern.match(item):
            # 项目标题（加粗）
            current_project = item
            p = doc.add_paragraph(current_project, style='Normal')
            for run in p.runs:
                run.bold = True
        elif current_project:
            # 项目内容缩进处理
            p = doc.add_paragraph(item, style='Normal')
            if item.startswith(('项目简介：', '技术栈：', '个人职责：')):
                p.paragraph_format.left_indent = Inches(0.2)
            elif re.match(r'^\d+、', item):  # 匹配数字序号（1、2、等）
                p.paragraph_format.left_indent = Inches(0.4)
            else:
                p.paragraph_format.left_indent = Inches(0.2)
        else:
            # 没有匹配到项目标题的内容
            p = doc.add_paragraph(item, style='Normal')
            logging.warning(f"项目经验中未归属项目的内容：{item}")


def add_self_evaluation(doc, eval_list):
    """添加自我评价部分"""
    doc.add_paragraph('自我评价', style='SectionStyle')
    for eval_item in eval_list:
        p = doc.add_paragraph(eval_item, style='Normal')
        if re.match(r'^\d+\.', eval_item):  # 匹配数字序号（1.、2.等）
            p.paragraph_format.left_indent = Inches(0.2)


def create_resume(content, output_file="个人简历.docx"):
    """生成简历主函数"""
    if not content.strip():
        logging.error("输入内容为空，无法生成简历")
        return

    # 创建文档对象
    doc = Document()

    # 设置页面边距
    for section in doc.sections:
        section.top_margin = Inches(0.8)
        section.bottom_margin = Inches(0.8)
        section.left_margin = Inches(1.2)
        section.right_margin = Inches(1.2)

    # 初始化样式
    init_styles(doc)

    # 添加标题
    doc.add_paragraph('个人简历', style='TitleStyle')

    # 解析内容
    sections = parse_content(content)

    # 按部分添加内容
    section_handlers = {
        '基本信息': add_basic_info,
        '教育背景': add_education,
        '求职意向': add_job_intention,
        '个人技能': add_skills,
        '工作经历': add_work_experience,
        '项目经验': add_project_experience,
        '自我评价': add_self_evaluation
    }

    for section_name, handler in section_handlers.items():
        if section_name in sections:
            handler(doc, sections[section_name])
        else:
            logging.info(f"未提供 {section_name} 内容，跳过该部分")

    # 保存文档（处理可能的IO错误）
    try:
        doc.save(output_file)
        logging.info(f"简历已成功生成：{output_file}")
    except IOError as e:
        logging.error(f"保存简历失败：{e}")


if __name__ == "__main__":
    # 示例简历内容（移除了原有的错误示例，如教育背景的"女"）
    resume_content = """# 个人简历
基本信息
姓    名：杨森                          性    别：男
年    龄：29                            手    机：183-0295-2449                   邮    箱：18302952449@163.com           工作经验：4年Java开发
教育背景
2013.9-2017.7  本科                       陕西科技大学
求职意向
期望职位：Java开发工程师                 期望地点：西安
目标薪资：面议                           当前状态：在职
个人技能
Ø 熟练掌握java基础知识，如 Lambda 表达式、Stream 流等；
Ø 熟练使用Spring、Spring Boot、Spring Cloud、MyBatis 等框架；
工作经历
2025.1-至今          西安辰信技术有限公司          java开发工程师
参与项目需求分析、原型设计；
2021.10-2025.1       中软国际                      java开发工程师
参与需求评审，IT方案评审，Code review；
项目经验
项目一：训战一体化平台
项目简介：
训战一体化平台是提供给陕煤集团神木红柳林矿业有限公司推进煤矿智能化建设项目...
技术栈：
Spring Boot + Mybatis + MySQL + Redis + RabbitMQ
个人职责：
1、核心微服务开发
独立设计并实现学习平台与互动社区两大微服务...
自我评价
1. 性格稳重，能够在压力环境下保持冷静...
2. 态度诚恳谦虚，易于与团队成员建立良好的合作关系...
"""

    create_resume(resume_content)
